﻿using Agile.Infra.Core.Guard;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System.Text.RegularExpressions;

namespace Agile.Infra.Core.Agile.Extensions
{
    public static class JsonExtensions
    {
        /// <summary>将当前Json字符串转为T类对象</summary>
        public static T ToJsonObject<T>(this string @this, params JsonConverter[] converters) where T : class
        => @this.IsNullOrWhiteSpace() ? default : JsonConvert.DeserializeObject<T>(@this, converters);

        /// <summary>将当前Json字符串转为Json对象</summary>
        public static dynamic ToJsonObject(this string @this)
        {
            return @this.IsNullOrWhiteSpace() ? null : JsonConvert.DeserializeObject(@this); ;
        }

        /// <summary>将对象转为Json字符串</summary>
        public static string ToJsonString(this object @this, string dateTimeformat = "yyyy-MM-dd HH:mm:ss")
        {
            var timeConverter = new IsoDateTimeConverter { DateTimeFormat = dateTimeformat };
            return @this.ToJsonString(timeConverter);
        }

        /// <summary>将对象转为Json字符串</summary>
        public static string ToJsonString(this object @this, params JsonConverter[] converters)
        => JsonConvert.SerializeObject(@this, converters);

        /// <summary>将对象转为Json字符串</summary>
        public static string ToJsonString(this object @this, bool ignoreNullValue)
        {
            if (ignoreNullValue)
            {
                var settings = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore };
                return JsonConvert.SerializeObject(@this, settings);
            }
            else
            {
                return ToJsonString(@this);
            }
        }

        /// <summary>
        /// 小驼峰输出忽略JsonProperty属性
        /// </summary>
        public class PropertyNameContractResolver : DefaultContractResolver
        {
            protected override IList<Newtonsoft.Json.Serialization.JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
            {
                var list = base.CreateProperties(type, memberSerialization);
                foreach (Newtonsoft.Json.Serialization.JsonProperty prop in list)
                {
                    prop.PropertyName = Regex.Replace(prop.UnderlyingName, "^[A-Z]", m => m.Value.ToLower());
                }
                return list;
            }
        }

        //public static string StringValue(this JToken @this, string key) => @this.Value<string>(Checker.Argument.IsNotEmpty(key, nameof(key)));

        //public static DateTime DateTimeValue(this JToken @this, string key) => @this.Value<DateTime>(Checker.Argument.IsNotEmpty(key, nameof(key)));

        //public static int IntValue(this JToken @this, string key) => @this.Value<int>(Checker.Argument.IsNotEmpty(key, nameof(key)));

        //public static float FloatValue(this JToken @this, string key) => @this.Value<float>(Checker.Argument.IsNotEmpty(key, nameof(key)));

    }
}
